const CPU_BLOCK_QUERY = '#cpu-svg';
const CPU_INFO = ['user', 'niced', 'system', 'idle', 'iowait', 'irq', 'soft irq'];

const MEM_BLOCK_QUERY = '#mem-svg';
const MEM_INFO = ['usage', 'free', 'avai', 'buffers', 'cached'];

const colorArr = ['#000', '#00aba9', '#ff0097', '#733878', '#2d89ef'];
const memColor = '#e74c3c';

const padding = {left: 30, right: 30, top: 20, bottom: 20};

function initCpuSvg(id, type, width = 200, height = 200) {
  let svg = d3.select(CPU_BLOCK_QUERY).append("svg").attr("width", width).attr("height", height).attr('id', id);


  //x轴的比例尺
  let xScale = d3.scaleOrdinal().domain(CPU_INFO).range([width - padding.left - padding.right, 0]);

  //y轴的比例尺
  let yScale = d3.scaleLinear().domain([0, 1]).range([height - padding.top - padding.bottom, 0]);

  //定义x轴
  let xAxis = d3.axisBottom(xScale).tickFormat((d) => '');

  //定义y轴
  let yAxis = d3.axisLeft(yScale).tickFormat((d) => {
    return parseInt(d * 100) + '%';
  });

  //添加x轴
  svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
    .call(xAxis);

  //添加y轴
  svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .call(yAxis);

  if (!type) {
    for (let i = 0; i < CPU_INFO.length; i++) {
      svg.append('text')
        .attr('class', 'cpu-x-label')
        .attr('x', (i + 1/2) * (width - padding.left - padding.right) / MEM_INFO.length + padding.left / 4)
        .attr('y', height - 20)
        .attr('dy', 8)
        .text(CPU_INFO[i]);
    }
    svg.append('text')
      .attr('class', 'label')
      .attr('x', width / 2 - 15)
      .attr('y', height - 10)
      .attr('dy', 10)
      .text(id.split('-')[0]);
  }
  return svg;
}

function drawCpuHistogramData(data, id, index) {
  let svg = d3.select('#' + id);

  const width = +svg.attr('width');
  const height = +svg.attr('height');
  //矩形之间的空白
  let rectPadding = 8;

  //x轴的比例
  let xScale = d3.scaleLinear().domain([0, CPU_INFO.length-1]).range([0, width - padding.left - padding.right]);

  //y轴的比例尺
  let yScale = d3.scaleLinear().domain([0, 1]).range([height - padding.top - padding.bottom, 0]);

  //添加矩形元素
  let rects = svg.selectAll(".MyRect").data(data);

  let t = d3.transition().duration(600);
  // create new elements as needed
  rects.enter()
    .append("rect")
    .attr("class", "MyRect")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .merge(rects)
    .attr("x", function (d, i) {
      return xScale(i) + rectPadding / 2 + 3;
    })
    .attr("y", function (d) {
      return yScale(d);
    })
    .attr("width", xScale(1) - xScale(0) - rectPadding)
    .attr("height", function (d) {
      return d === 0 ? 2 : height - padding.top - padding.bottom - yScale(d);
    })
    .attr("fill", colorArr[index]);

  // remove old elements
  rects.exit().remove();

  //添加文字元素
  let texts = svg.selectAll(".MyText").data(data);
  texts.enter()
    .append("text")
    .attr("class", "MyText")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .merge(texts)
    .attr("x", function (d, i) {
      return xScale(i) - 5;
    })
    .attr("y", function (d) {
      return yScale(d) - 30;
    })
    .attr("dx", function () {
      return (xScale(1) - xScale(0) - rectPadding) / 2;
    })
    .attr("dy", function (d) {
      return 20;
    })
    .text(function (d) {
      return (d * 100).toFixed(1);
    });

  texts.exit().remove();
}

function drawCpuLineChartData(datas, id) {
  let svg = d3.select('#' + id);
  let width = +svg.attr('width');
  let height = +svg.attr('height');

  let xScale = d3.scaleLinear().domain([0, datas[0].length - 1]).rangeRound([padding.left, width - padding.right]);
  let yScale = d3.scaleLinear().domain([0, 1]).rangeRound([height - padding.top, padding.bottom]);
  let line = d3.line()
    .x((d) => xScale(d.index))
    .y((d) => yScale(d.usage));
  // clear old path
  svg.selectAll("path.line").remove();
  for (let [index, data] of datas.entries()) {
    svg.append('path')
      .datum(data)
      .attr('class', 'line')
      .attr('fill', 'none')
      .attr('stroke', colorArr[index])
      .attr('stroke-linejoin', 'round')
      .attr('stroke-linecap', 'round')
      .attr('stroke-width', 1)
      .attr('d', line(data))
  }
}

function drawCpuLineChart(data, id, isNew) {
  if (isNew) {
    initCpuSvg(id, 2, 400, 200);
  }
  else {
    drawCpuLineChartData(data, id);
  }
}

function drawCpuHistogram(data, id, isNew) {
  if (isNew) {
    initCpuSvg(id);
  }
  else {
    drawCpuHistogramData(data, id, Number(/\d+/.exec(id)[0]) + 1)
  }
}

function initMemSvg(id, type, width=400, height=200) {
  let svg = d3.select(MEM_BLOCK_QUERY).append("svg").attr("width", width).attr("height", height).attr('id', id);


  //x轴的比例尺
  let xScale = d3.scaleOrdinal().domain(CPU_INFO).range([width - padding.left - padding.right, 0]);

  //y轴的比例尺
  let yScale = d3.scaleLinear().domain([0, 1]).range([height - padding.top - padding.bottom, 0]);

  //定义x轴
  let xAxis = d3.axisBottom(xScale).tickFormat((d) => '');

  //定义y轴
  let yAxis = d3.axisLeft(yScale).tickFormat((d) => {
    return parseInt(d * 100) + '%';
  });

  //添加x轴
  svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
    .call(xAxis);

  //添加y轴
  svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .call(yAxis);

  if (type === 2) {
    for (let i = 0; i < MEM_INFO.length; i++) {
      svg.append('text')
        .attr('class', 'x-label')
        .attr('x', (i + 1/2) * (width - padding.left - padding.right) / MEM_INFO.length + padding.left / 2 - 4)
        .attr('y', height - 20)
        .attr('dy', 15)
        .text(MEM_INFO[i]);
    }
  }

  return svg;
}

function drawMemLineChartData(id, data) {
  let svg = d3.select('#' + id);
  let width = +svg.attr('width');
  let height = +svg.attr('height');

  let xScale = d3.scaleLinear().domain([0, data.length - 1]).rangeRound([padding.left, width - padding.right]);
  let yScale = d3.scaleLinear().domain([0, 1]).rangeRound([height - padding.top, padding.bottom]);
  let line = d3.line()
    .x((d) => xScale(d.index))
    .y((d) => yScale(d.usage));
  // clear old path
  svg.selectAll("path.line").remove();
  svg.append('path')
    .datum(data)
    .attr('class', 'line')
    .attr('fill', 'none')
    .attr('stroke', memColor)
    .attr('stroke-linejoin', 'round')
    .attr('stroke-linecap', 'round')
    .attr('stroke-width', 2)
    .attr('d', line(data))
}

function drawMemLineChart(data, id, isNew) {
  if (isNew) {
    initMemSvg(id, 1);
  }
  else {
    drawMemLineChartData(id, data);
  }
}

function drawMemHistogram(data, id) {
  let svg = d3.select('#' + id);
  if (svg.empty()) {
    svg = initMemSvg(id, 2);
  }
  const width = +svg.attr('width');
  const height = +svg.attr('height');
  //矩形之间的空白
  let rectPadding = 8;

  //x轴的比例
  let xScale = d3.scaleLinear().domain([0, MEM_INFO.length]).rangeRound([0, width - padding.left - padding.right]);

  //y轴的比例尺
  let yScale = d3.scaleLinear().domain([0, data[data.length-1]]).rangeRound([height - padding.top - padding.bottom, 0]);

  //添加矩形元素
  let rects = svg.selectAll(".MyRect").data(data.slice(0, -1));

  let t = d3.transition().duration(500);
  // create new elements as needed
  rects.enter()
    .append("rect")
    .attr("class", "MyRect")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .merge(rects)
    .attr("x", function (d, i) {
      return xScale(i) + rectPadding / 2;
    })
    .attr("y", function (d) {
      return yScale(d);
    })
    .attr("width", xScale(1) - xScale(0) - rectPadding)
    .attr("height", function (d) {
      return d === 0 ? 2 : height - padding.top - padding.bottom - yScale(d);
    })
    .attr("fill", memColor);

  // remove old elements
  rects.exit().remove();

  //添加文字元素
  let texts = svg.selectAll(".MyText").data(data.slice(0, -1));
  texts.enter()
    .append("text")
    .attr("class", "MyText")
    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
    .merge(texts)
    .attr("x", function (d, i) {
      return xScale(i) - 15;
    })
    .attr("y", function (d) {
      return yScale(d) - 30;
    })
    .attr("dx", function () {
      return (xScale(1) - xScale(0) - rectPadding) / 2;
    })
    .attr("dy", function (d) {
      return 20;
    })
    .text(function (d) {
      return d.toFixed(1) + ' Mb';
    });

  texts.exit().remove();
}

module.exports = {
  drawCpuHistogram: drawCpuHistogram,
  drawCpuLineChart: drawCpuLineChart,
  drawMemLineChart: drawMemLineChart,
  drawMemHistogram: drawMemHistogram
};
